#
# Copyright (C) [2024] Xingyun Integrated Circuit, Inc.
#
# GreenCode was a private technology asset of Xingyun Integrated Circuit， Inc （Confidential）
# Author: Shawn.Tan
# Date: 2025.10.28
#
# History: Initial Version 2025.10.28
#
#
import RandomUtils
import StateTransition
from Enums import EStateElementType
from State import State

import state_transition_test_utils
from base.Sequence import Sequence
from gpgpu.EnvGPGPU import EnvGPGPU
from gpgpu.GenThreadGPGPU import GenThreadGPGPU


# This test verifies that the default MemoryStateElement
# StateTransitionHandler alters the memory State as expected.
class MainSequence(Sequence):
    def __init__(self, aGenThread, aName=None):
        super().__init__(aGenThread, aName)

        self._mMemBlockStartAddr = None
        self._mMemBlockEndAddr = None
        self._mExpectedStateData = {}

    def generate(self, **kargs):
        state = self._createState()

        target_addr_range = "%d-%d" % (
            self._mMemBlockStartAddr,
            self._mMemBlockEndAddr,
        )

        if self.getGlobalState("AppRegisterWidth") == 32:
            instructions = ("LW##CALM", "SW##CALM")
        else:
            instructions = ("LD##CALM", "SD##CALM")

        for _ in range(RandomUtils.random32(2, 5)):
            for _ in range(RandomUtils.random32(50, 100)):
                self.genInstruction(self.choice(instructions), {"LSTarget": target_addr_range})

            StateTransition.transitionToState(state)
            state_transition_test_utils.verify_state(self, self._mExpectedStateData)

    # Create a simple State to test an explicit StateTransition.
    def _createState(self):
        state = State()

        expected_mem_state_data = []
        mem_block_size = RandomUtils.random32(0x8, 0x20) * 16
        self._mMemBlockStartAddr = self.genVA(Size=mem_block_size, Align=16, Type="D")
        self._mMemBlockEndAddr = self._mMemBlockStartAddr + mem_block_size - 1
        cur_addr = self._mMemBlockStartAddr
        while cur_addr <= self._mMemBlockEndAddr:
            if self.getGlobalState("AppRegisterWidth") == 32:
                mem_val = RandomUtils.random32()
                state.addMemoryStateElement(cur_addr, 4, mem_val)
                expected_mem_state_data.append((cur_addr, mem_val))
                cur_addr += 4
            else:
                mem_val = RandomUtils.random64()
                state.addMemoryStateElement(cur_addr, 8, mem_val)
                expected_mem_state_data.append((cur_addr, mem_val))
                cur_addr += 8

        self._mExpectedStateData[EStateElementType.Memory] = expected_mem_state_data

        return state


MainSequenceClass = MainSequence
GenThreadClass = GenThreadGPGPU
EnvClass = EnvGPGPU
